//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension S3Vectors {
    // MARK: Enums

    public enum DataType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case float32 = "float32"
        public var description: String { return self.rawValue }
    }

    public enum DistanceMetric: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case cosine = "cosine"
        case euclidean = "euclidean"
        public var description: String { return self.rawValue }
    }

    public enum SseType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case aes256 = "AES256"
        case awsKms = "aws:kms"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct CreateIndexInput: AWSEncodableShape {
        /// The data type of the vectors to be inserted into the vector index.
        public let dataType: DataType
        /// The dimensions of the vectors to be inserted into the vector index.
        public let dimension: Int
        /// The distance metric to be used for similarity search.
        public let distanceMetric: DistanceMetric
        /// The name of the vector index to create.
        public let indexName: String
        /// The metadata configuration for the vector index.
        public let metadataConfiguration: MetadataConfiguration?
        /// The Amazon Resource Name (ARN) of the vector bucket to create the vector index in.
        public let vectorBucketArn: String?
        /// The name of the vector bucket to create the vector index in.
        public let vectorBucketName: String?

        @inlinable
        public init(dataType: DataType, dimension: Int, distanceMetric: DistanceMetric, indexName: String, metadataConfiguration: MetadataConfiguration? = nil, vectorBucketArn: String? = nil, vectorBucketName: String? = nil) {
            self.dataType = dataType
            self.dimension = dimension
            self.distanceMetric = distanceMetric
            self.indexName = indexName
            self.metadataConfiguration = metadataConfiguration
            self.vectorBucketArn = vectorBucketArn
            self.vectorBucketName = vectorBucketName
        }

        public func validate(name: String) throws {
            try self.validate(self.dimension, name: "dimension", parent: name, max: 4096)
            try self.validate(self.dimension, name: "dimension", parent: name, min: 1)
            try self.validate(self.indexName, name: "indexName", parent: name, max: 63)
            try self.validate(self.indexName, name: "indexName", parent: name, min: 3)
            try self.metadataConfiguration?.validate(name: "\(name).metadataConfiguration")
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, max: 63)
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, min: 3)
        }

        private enum CodingKeys: String, CodingKey {
            case dataType = "dataType"
            case dimension = "dimension"
            case distanceMetric = "distanceMetric"
            case indexName = "indexName"
            case metadataConfiguration = "metadataConfiguration"
            case vectorBucketArn = "vectorBucketArn"
            case vectorBucketName = "vectorBucketName"
        }
    }

    public struct CreateIndexOutput: AWSDecodableShape {
        public init() {}
    }

    public struct CreateVectorBucketInput: AWSEncodableShape {
        /// The encryption configuration for the vector bucket. By default, if you don't specify, all new vectors in Amazon S3 vector buckets use server-side encryption with Amazon S3 managed keys (SSE-S3), specifically AES256.
        public let encryptionConfiguration: EncryptionConfiguration?
        /// The name of the vector bucket to create.
        public let vectorBucketName: String

        @inlinable
        public init(encryptionConfiguration: EncryptionConfiguration? = nil, vectorBucketName: String) {
            self.encryptionConfiguration = encryptionConfiguration
            self.vectorBucketName = vectorBucketName
        }

        public func validate(name: String) throws {
            try self.encryptionConfiguration?.validate(name: "\(name).encryptionConfiguration")
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, max: 63)
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, min: 3)
        }

        private enum CodingKeys: String, CodingKey {
            case encryptionConfiguration = "encryptionConfiguration"
            case vectorBucketName = "vectorBucketName"
        }
    }

    public struct CreateVectorBucketOutput: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteIndexInput: AWSEncodableShape {
        /// The ARN of the vector index to delete.
        public let indexArn: String?
        /// The name of the vector index to delete.
        public let indexName: String?
        /// The name of the vector bucket that contains the vector index.
        public let vectorBucketName: String?

        @inlinable
        public init(indexArn: String? = nil, indexName: String? = nil, vectorBucketName: String? = nil) {
            self.indexArn = indexArn
            self.indexName = indexName
            self.vectorBucketName = vectorBucketName
        }

        public func validate(name: String) throws {
            try self.validate(self.indexName, name: "indexName", parent: name, max: 63)
            try self.validate(self.indexName, name: "indexName", parent: name, min: 3)
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, max: 63)
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, min: 3)
        }

        private enum CodingKeys: String, CodingKey {
            case indexArn = "indexArn"
            case indexName = "indexName"
            case vectorBucketName = "vectorBucketName"
        }
    }

    public struct DeleteIndexOutput: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteVectorBucketInput: AWSEncodableShape {
        /// The ARN of the vector bucket to delete.
        public let vectorBucketArn: String?
        /// The name of the vector bucket to delete.
        public let vectorBucketName: String?

        @inlinable
        public init(vectorBucketArn: String? = nil, vectorBucketName: String? = nil) {
            self.vectorBucketArn = vectorBucketArn
            self.vectorBucketName = vectorBucketName
        }

        public func validate(name: String) throws {
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, max: 63)
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, min: 3)
        }

        private enum CodingKeys: String, CodingKey {
            case vectorBucketArn = "vectorBucketArn"
            case vectorBucketName = "vectorBucketName"
        }
    }

    public struct DeleteVectorBucketOutput: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteVectorBucketPolicyInput: AWSEncodableShape {
        /// The ARN of the vector bucket to delete the policy from.
        public let vectorBucketArn: String?
        /// The name of the vector bucket to delete the policy from.
        public let vectorBucketName: String?

        @inlinable
        public init(vectorBucketArn: String? = nil, vectorBucketName: String? = nil) {
            self.vectorBucketArn = vectorBucketArn
            self.vectorBucketName = vectorBucketName
        }

        public func validate(name: String) throws {
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, max: 63)
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, min: 3)
        }

        private enum CodingKeys: String, CodingKey {
            case vectorBucketArn = "vectorBucketArn"
            case vectorBucketName = "vectorBucketName"
        }
    }

    public struct DeleteVectorBucketPolicyOutput: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteVectorsInput: AWSEncodableShape {
        /// The ARN of the vector index that contains a vector you want to delete.
        public let indexArn: String?
        /// The name of the vector index that contains a vector you want to delete.
        public let indexName: String?
        /// The keys of the vectors to delete.
        public let keys: [String]
        /// The name of the vector bucket that contains the vector index.
        public let vectorBucketName: String?

        @inlinable
        public init(indexArn: String? = nil, indexName: String? = nil, keys: [String], vectorBucketName: String? = nil) {
            self.indexArn = indexArn
            self.indexName = indexName
            self.keys = keys
            self.vectorBucketName = vectorBucketName
        }

        public func validate(name: String) throws {
            try self.validate(self.indexName, name: "indexName", parent: name, max: 63)
            try self.validate(self.indexName, name: "indexName", parent: name, min: 3)
            try self.keys.forEach {
                try validate($0, name: "keys[]", parent: name, max: 1024)
                try validate($0, name: "keys[]", parent: name, min: 1)
            }
            try self.validate(self.keys, name: "keys", parent: name, max: 500)
            try self.validate(self.keys, name: "keys", parent: name, min: 1)
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, max: 63)
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, min: 3)
        }

        private enum CodingKeys: String, CodingKey {
            case indexArn = "indexArn"
            case indexName = "indexName"
            case keys = "keys"
            case vectorBucketName = "vectorBucketName"
        }
    }

    public struct DeleteVectorsOutput: AWSDecodableShape {
        public init() {}
    }

    public struct EncryptionConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// Amazon Web Services Key Management Service (KMS) customer managed key ID to use for the encryption configuration. This parameter is allowed if and only if sseType is set to aws:kms. To specify the KMS key, you must use the format of the KMS key Amazon Resource Name (ARN). For example, specify Key ARN in the following format: arn:aws:kms:us-east-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab
        public let kmsKeyArn: String?
        /// The server-side encryption type to use for the encryption configuration of the vector bucket. By default, if you don't specify, all new vectors in Amazon S3 vector buckets use server-side encryption with Amazon S3 managed keys (SSE-S3), specifically AES256.
        public let sseType: SseType?

        @inlinable
        public init(kmsKeyArn: String? = nil, sseType: SseType? = nil) {
            self.kmsKeyArn = kmsKeyArn
            self.sseType = sseType
        }

        public func validate(name: String) throws {
            try self.validate(self.kmsKeyArn, name: "kmsKeyArn", parent: name, max: 2048)
            try self.validate(self.kmsKeyArn, name: "kmsKeyArn", parent: name, min: 1)
            try self.validate(self.kmsKeyArn, name: "kmsKeyArn", parent: name, pattern: "^(arn:aws[-a-z0-9]*:kms:[-a-z0-9]*:[0-9]{12}:key/.+)$")
        }

        private enum CodingKeys: String, CodingKey {
            case kmsKeyArn = "kmsKeyArn"
            case sseType = "sseType"
        }
    }

    public struct GetIndexInput: AWSEncodableShape {
        /// The ARN of the vector index.
        public let indexArn: String?
        /// The name of the vector index.
        public let indexName: String?
        /// The name of the vector bucket that contains the vector index.
        public let vectorBucketName: String?

        @inlinable
        public init(indexArn: String? = nil, indexName: String? = nil, vectorBucketName: String? = nil) {
            self.indexArn = indexArn
            self.indexName = indexName
            self.vectorBucketName = vectorBucketName
        }

        public func validate(name: String) throws {
            try self.validate(self.indexName, name: "indexName", parent: name, max: 63)
            try self.validate(self.indexName, name: "indexName", parent: name, min: 3)
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, max: 63)
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, min: 3)
        }

        private enum CodingKeys: String, CodingKey {
            case indexArn = "indexArn"
            case indexName = "indexName"
            case vectorBucketName = "vectorBucketName"
        }
    }

    public struct GetIndexOutput: AWSDecodableShape {
        /// The attributes of the vector index.
        public let index: Index

        @inlinable
        public init(index: Index) {
            self.index = index
        }

        private enum CodingKeys: String, CodingKey {
            case index = "index"
        }
    }

    public struct GetOutputVector: AWSDecodableShape {
        /// The vector data of the vector.
        public let data: VectorData?
        /// The name of the vector.
        public let key: String
        /// Metadata about the vector.
        public let metadata: AWSDocument?

        @inlinable
        public init(data: VectorData? = nil, key: String, metadata: AWSDocument? = nil) {
            self.data = data
            self.key = key
            self.metadata = metadata
        }

        private enum CodingKeys: String, CodingKey {
            case data = "data"
            case key = "key"
            case metadata = "metadata"
        }
    }

    public struct GetVectorBucketInput: AWSEncodableShape {
        /// The ARN of the vector bucket to retrieve information about.
        public let vectorBucketArn: String?
        /// The name of the vector bucket to retrieve information about.
        public let vectorBucketName: String?

        @inlinable
        public init(vectorBucketArn: String? = nil, vectorBucketName: String? = nil) {
            self.vectorBucketArn = vectorBucketArn
            self.vectorBucketName = vectorBucketName
        }

        public func validate(name: String) throws {
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, max: 63)
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, min: 3)
        }

        private enum CodingKeys: String, CodingKey {
            case vectorBucketArn = "vectorBucketArn"
            case vectorBucketName = "vectorBucketName"
        }
    }

    public struct GetVectorBucketOutput: AWSDecodableShape {
        /// The attributes of the vector bucket.
        public let vectorBucket: VectorBucket

        @inlinable
        public init(vectorBucket: VectorBucket) {
            self.vectorBucket = vectorBucket
        }

        private enum CodingKeys: String, CodingKey {
            case vectorBucket = "vectorBucket"
        }
    }

    public struct GetVectorBucketPolicyInput: AWSEncodableShape {
        /// The ARN of the vector bucket.
        public let vectorBucketArn: String?
        /// The name of the vector bucket.
        public let vectorBucketName: String?

        @inlinable
        public init(vectorBucketArn: String? = nil, vectorBucketName: String? = nil) {
            self.vectorBucketArn = vectorBucketArn
            self.vectorBucketName = vectorBucketName
        }

        public func validate(name: String) throws {
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, max: 63)
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, min: 3)
        }

        private enum CodingKeys: String, CodingKey {
            case vectorBucketArn = "vectorBucketArn"
            case vectorBucketName = "vectorBucketName"
        }
    }

    public struct GetVectorBucketPolicyOutput: AWSDecodableShape {
        /// The JSON that defines the policy.
        public let policy: String?

        @inlinable
        public init(policy: String? = nil) {
            self.policy = policy
        }

        private enum CodingKeys: String, CodingKey {
            case policy = "policy"
        }
    }

    public struct GetVectorsInput: AWSEncodableShape {
        /// The ARN of the vector index.
        public let indexArn: String?
        /// The name of the vector index.
        public let indexName: String?
        /// The names of the vectors you want to return attributes for.
        public let keys: [String]
        /// Indicates whether to include the vector data in the response. The default value is false.
        public let returnData: Bool?
        /// Indicates whether to include metadata in the response. The default value is false.
        public let returnMetadata: Bool?
        /// The name of the vector bucket that contains the vector index.
        public let vectorBucketName: String?

        @inlinable
        public init(indexArn: String? = nil, indexName: String? = nil, keys: [String], returnData: Bool? = nil, returnMetadata: Bool? = nil, vectorBucketName: String? = nil) {
            self.indexArn = indexArn
            self.indexName = indexName
            self.keys = keys
            self.returnData = returnData
            self.returnMetadata = returnMetadata
            self.vectorBucketName = vectorBucketName
        }

        public func validate(name: String) throws {
            try self.validate(self.indexName, name: "indexName", parent: name, max: 63)
            try self.validate(self.indexName, name: "indexName", parent: name, min: 3)
            try self.keys.forEach {
                try validate($0, name: "keys[]", parent: name, max: 1024)
                try validate($0, name: "keys[]", parent: name, min: 1)
            }
            try self.validate(self.keys, name: "keys", parent: name, max: 100)
            try self.validate(self.keys, name: "keys", parent: name, min: 1)
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, max: 63)
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, min: 3)
        }

        private enum CodingKeys: String, CodingKey {
            case indexArn = "indexArn"
            case indexName = "indexName"
            case keys = "keys"
            case returnData = "returnData"
            case returnMetadata = "returnMetadata"
            case vectorBucketName = "vectorBucketName"
        }
    }

    public struct GetVectorsOutput: AWSDecodableShape {
        /// The attributes of the vectors.
        public let vectors: [GetOutputVector]

        @inlinable
        public init(vectors: [GetOutputVector]) {
            self.vectors = vectors
        }

        private enum CodingKeys: String, CodingKey {
            case vectors = "vectors"
        }
    }

    public struct Index: AWSDecodableShape {
        /// Date and time when the vector index was created.
        public let creationTime: Date
        /// The data type of the vectors inserted into the vector index.
        public let dataType: DataType
        /// The number of values in the vectors that are inserted into the vector index.
        public let dimension: Int
        /// The distance metric to be used for similarity search.
        public let distanceMetric: DistanceMetric
        /// The Amazon Resource Name (ARN) of the vector index.
        public let indexArn: String
        /// The name of the vector index.
        public let indexName: String
        /// The metadata configuration for the vector index.
        public let metadataConfiguration: MetadataConfiguration?
        /// The name of the vector bucket that contains the vector index.
        public let vectorBucketName: String

        @inlinable
        public init(creationTime: Date, dataType: DataType, dimension: Int, distanceMetric: DistanceMetric, indexArn: String, indexName: String, metadataConfiguration: MetadataConfiguration? = nil, vectorBucketName: String) {
            self.creationTime = creationTime
            self.dataType = dataType
            self.dimension = dimension
            self.distanceMetric = distanceMetric
            self.indexArn = indexArn
            self.indexName = indexName
            self.metadataConfiguration = metadataConfiguration
            self.vectorBucketName = vectorBucketName
        }

        private enum CodingKeys: String, CodingKey {
            case creationTime = "creationTime"
            case dataType = "dataType"
            case dimension = "dimension"
            case distanceMetric = "distanceMetric"
            case indexArn = "indexArn"
            case indexName = "indexName"
            case metadataConfiguration = "metadataConfiguration"
            case vectorBucketName = "vectorBucketName"
        }
    }

    public struct IndexSummary: AWSDecodableShape {
        /// Date and time when the vector index was created.
        public let creationTime: Date
        /// The Amazon Resource Name (ARN) of the vector index.
        public let indexArn: String
        /// The name of the vector index.
        public let indexName: String
        /// The name of the vector bucket that contains the vector index.
        public let vectorBucketName: String

        @inlinable
        public init(creationTime: Date, indexArn: String, indexName: String, vectorBucketName: String) {
            self.creationTime = creationTime
            self.indexArn = indexArn
            self.indexName = indexName
            self.vectorBucketName = vectorBucketName
        }

        private enum CodingKeys: String, CodingKey {
            case creationTime = "creationTime"
            case indexArn = "indexArn"
            case indexName = "indexName"
            case vectorBucketName = "vectorBucketName"
        }
    }

    public struct ListIndexesInput: AWSEncodableShape {
        /// The maximum number of items to be returned in the response.
        public let maxResults: Int?
        /// The previous pagination token.
        public let nextToken: String?
        /// Limits the response to vector indexes that begin with the specified prefix.
        public let prefix: String?
        /// The ARN of the vector bucket that contains the vector indexes.
        public let vectorBucketArn: String?
        /// The name of the vector bucket that contains the vector indexes.
        public let vectorBucketName: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil, prefix: String? = nil, vectorBucketArn: String? = nil, vectorBucketName: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.prefix = prefix
            self.vectorBucketArn = vectorBucketArn
            self.vectorBucketName = vectorBucketName
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 500)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 512)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.prefix, name: "prefix", parent: name, max: 63)
            try self.validate(self.prefix, name: "prefix", parent: name, min: 1)
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, max: 63)
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, min: 3)
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "maxResults"
            case nextToken = "nextToken"
            case prefix = "prefix"
            case vectorBucketArn = "vectorBucketArn"
            case vectorBucketName = "vectorBucketName"
        }
    }

    public struct ListIndexesOutput: AWSDecodableShape {
        /// The attributes of the vector indexes
        public let indexes: [IndexSummary]
        /// The next pagination token.
        public let nextToken: String?

        @inlinable
        public init(indexes: [IndexSummary], nextToken: String? = nil) {
            self.indexes = indexes
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case indexes = "indexes"
            case nextToken = "nextToken"
        }
    }

    public struct ListOutputVector: AWSDecodableShape {
        /// The vector data of the vector.
        public let data: VectorData?
        /// The name of the vector.
        public let key: String
        /// Metadata about the vector.
        public let metadata: AWSDocument?

        @inlinable
        public init(data: VectorData? = nil, key: String, metadata: AWSDocument? = nil) {
            self.data = data
            self.key = key
            self.metadata = metadata
        }

        private enum CodingKeys: String, CodingKey {
            case data = "data"
            case key = "key"
            case metadata = "metadata"
        }
    }

    public struct ListVectorBucketsInput: AWSEncodableShape {
        /// The maximum number of vector buckets to be returned in the response.
        public let maxResults: Int?
        /// The previous pagination token.
        public let nextToken: String?
        /// Limits the response to vector buckets that begin with the specified prefix.
        public let prefix: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil, prefix: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.prefix = prefix
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 500)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 512)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.prefix, name: "prefix", parent: name, max: 63)
            try self.validate(self.prefix, name: "prefix", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "maxResults"
            case nextToken = "nextToken"
            case prefix = "prefix"
        }
    }

    public struct ListVectorBucketsOutput: AWSDecodableShape {
        /// The element is included in the response when there are more buckets to be listed with pagination.
        public let nextToken: String?
        /// The list of vector buckets owned by the requester.
        public let vectorBuckets: [VectorBucketSummary]

        @inlinable
        public init(nextToken: String? = nil, vectorBuckets: [VectorBucketSummary]) {
            self.nextToken = nextToken
            self.vectorBuckets = vectorBuckets
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "nextToken"
            case vectorBuckets = "vectorBuckets"
        }
    }

    public struct ListVectorsInput: AWSEncodableShape {
        /// The Amazon resource Name (ARN) of the vector index.
        public let indexArn: String?
        /// The name of the vector index.
        public let indexName: String?
        /// The maximum number of vectors to return on a page. If you don't specify maxResults, the ListVectors operation uses a default value of 500. If the processed dataset size exceeds 1 MB before reaching the maxResults value, the operation stops and returns the vectors that are retrieved up to that point, along with a nextToken that you can use in a subsequent request to retrieve the next set of results.
        public let maxResults: Int?
        /// Pagination token from a previous request. The value of this field is empty for an initial request.
        public let nextToken: String?
        /// If true, the vector data of each vector will be included in the response. The default value is false.
        public let returnData: Bool?
        /// If true, the metadata associated with each vector will be included in the response. The default value is false.
        public let returnMetadata: Bool?
        /// For a parallel ListVectors request, segmentCount represents the total number of vector segments into which the ListVectors operation will be divided. The value of segmentCount corresponds to the number of application workers that will perform the parallel ListVectors operation. For example, if you want to use four application threads to list vectors in a vector index, specify a segmentCount value of 4.  If you specify a segmentCount value of 1, the ListVectors operation will be sequential rather than parallel. If you specify segmentCount, you must also specify segmentIndex.
        public let segmentCount: Int?
        /// For a parallel ListVectors request, segmentIndex is the index of the segment from which to list vectors in the current request. It identifies an individual segment to be listed by an application worker.  Segment IDs are zero-based, so the first segment is always 0. For example, if you want to use four application threads to list vectors in a vector index, then the first thread specifies a segmentIndex value of 0, the second thread specifies 1, and so on.  The value of segmentIndex must be less than the value provided for segmentCount.  If you provide segmentIndex, you must also provide segmentCount.
        public let segmentIndex: Int?
        /// The name of the vector bucket.
        public let vectorBucketName: String?

        @inlinable
        public init(indexArn: String? = nil, indexName: String? = nil, maxResults: Int? = nil, nextToken: String? = nil, returnData: Bool? = nil, returnMetadata: Bool? = nil, segmentCount: Int? = nil, segmentIndex: Int? = nil, vectorBucketName: String? = nil) {
            self.indexArn = indexArn
            self.indexName = indexName
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.returnData = returnData
            self.returnMetadata = returnMetadata
            self.segmentCount = segmentCount
            self.segmentIndex = segmentIndex
            self.vectorBucketName = vectorBucketName
        }

        public func validate(name: String) throws {
            try self.validate(self.indexName, name: "indexName", parent: name, max: 63)
            try self.validate(self.indexName, name: "indexName", parent: name, min: 3)
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 1000)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.segmentCount, name: "segmentCount", parent: name, max: 16)
            try self.validate(self.segmentCount, name: "segmentCount", parent: name, min: 1)
            try self.validate(self.segmentIndex, name: "segmentIndex", parent: name, max: 15)
            try self.validate(self.segmentIndex, name: "segmentIndex", parent: name, min: 0)
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, max: 63)
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, min: 3)
        }

        private enum CodingKeys: String, CodingKey {
            case indexArn = "indexArn"
            case indexName = "indexName"
            case maxResults = "maxResults"
            case nextToken = "nextToken"
            case returnData = "returnData"
            case returnMetadata = "returnMetadata"
            case segmentCount = "segmentCount"
            case segmentIndex = "segmentIndex"
            case vectorBucketName = "vectorBucketName"
        }
    }

    public struct ListVectorsOutput: AWSDecodableShape {
        /// Pagination token to be used in the subsequent request. The field is empty if no further pagination is required.
        public let nextToken: String?
        /// Vectors in the current segment.
        public let vectors: [ListOutputVector]

        @inlinable
        public init(nextToken: String? = nil, vectors: [ListOutputVector]) {
            self.nextToken = nextToken
            self.vectors = vectors
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "nextToken"
            case vectors = "vectors"
        }
    }

    public struct MetadataConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// Non-filterable metadata keys allow you to enrich vectors with additional context during storage and retrieval. Unlike default metadata keys, these keys can’t be used as query filters. Non-filterable metadata keys can be retrieved but can’t be searched, queried, or filtered. You can access non-filterable metadata keys of your vectors after finding the vectors. For more information about non-filterable metadata keys, see Vectors and Limitations and restrictions in the Amazon S3 User Guide.
        public let nonFilterableMetadataKeys: [String]

        @inlinable
        public init(nonFilterableMetadataKeys: [String]) {
            self.nonFilterableMetadataKeys = nonFilterableMetadataKeys
        }

        public func validate(name: String) throws {
            try self.nonFilterableMetadataKeys.forEach {
                try validate($0, name: "nonFilterableMetadataKeys[]", parent: name, max: 63)
                try validate($0, name: "nonFilterableMetadataKeys[]", parent: name, min: 1)
            }
            try self.validate(self.nonFilterableMetadataKeys, name: "nonFilterableMetadataKeys", parent: name, max: 10)
            try self.validate(self.nonFilterableMetadataKeys, name: "nonFilterableMetadataKeys", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case nonFilterableMetadataKeys = "nonFilterableMetadataKeys"
        }
    }

    public struct PutInputVector: AWSEncodableShape {
        /// The vector data of the vector.  Vector dimensions must match the dimension count that's configured for the vector index.   For the cosine distance metric, zero vectors (vectors containing all zeros) aren't allowed.   For both cosine and euclidean distance metrics, vector data must contain only valid floating-point values. Invalid values such as NaN (Not a Number) or Infinity aren't allowed.
        public let data: VectorData
        /// The name of the vector. The key uniquely identifies the vector in a vector index.
        public let key: String
        /// Metadata about the vector. All metadata entries undergo validation to ensure they meet the format requirements for size and data types.
        public let metadata: AWSDocument?

        @inlinable
        public init(data: VectorData, key: String, metadata: AWSDocument? = nil) {
            self.data = data
            self.key = key
            self.metadata = metadata
        }

        public func validate(name: String) throws {
            try self.validate(self.key, name: "key", parent: name, max: 1024)
            try self.validate(self.key, name: "key", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case data = "data"
            case key = "key"
            case metadata = "metadata"
        }
    }

    public struct PutVectorBucketPolicyInput: AWSEncodableShape {
        /// The JSON that defines the policy. For more information about bucket policies for S3 Vectors, see Managing vector bucket policies in the Amazon S3 User Guide.
        public let policy: String
        /// The Amazon Resource Name (ARN) of the vector bucket.
        public let vectorBucketArn: String?
        /// The name of the vector bucket.
        public let vectorBucketName: String?

        @inlinable
        public init(policy: String, vectorBucketArn: String? = nil, vectorBucketName: String? = nil) {
            self.policy = policy
            self.vectorBucketArn = vectorBucketArn
            self.vectorBucketName = vectorBucketName
        }

        public func validate(name: String) throws {
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, max: 63)
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, min: 3)
        }

        private enum CodingKeys: String, CodingKey {
            case policy = "policy"
            case vectorBucketArn = "vectorBucketArn"
            case vectorBucketName = "vectorBucketName"
        }
    }

    public struct PutVectorBucketPolicyOutput: AWSDecodableShape {
        public init() {}
    }

    public struct PutVectorsInput: AWSEncodableShape {
        /// The ARN of the vector index where you want to write vectors.
        public let indexArn: String?
        /// The name of the vector index where you want to write vectors.
        public let indexName: String?
        /// The name of the vector bucket that contains the vector index.
        public let vectorBucketName: String?
        /// The vectors to add to a vector index. The number of vectors in a single request must not exceed the resource capacity, otherwise the request will be rejected with the error ServiceUnavailableException with the error message "Currently unable to handle the request".
        public let vectors: [PutInputVector]

        @inlinable
        public init(indexArn: String? = nil, indexName: String? = nil, vectorBucketName: String? = nil, vectors: [PutInputVector]) {
            self.indexArn = indexArn
            self.indexName = indexName
            self.vectorBucketName = vectorBucketName
            self.vectors = vectors
        }

        public func validate(name: String) throws {
            try self.validate(self.indexName, name: "indexName", parent: name, max: 63)
            try self.validate(self.indexName, name: "indexName", parent: name, min: 3)
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, max: 63)
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, min: 3)
            try self.vectors.forEach {
                try $0.validate(name: "\(name).vectors[]")
            }
            try self.validate(self.vectors, name: "vectors", parent: name, max: 500)
            try self.validate(self.vectors, name: "vectors", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case indexArn = "indexArn"
            case indexName = "indexName"
            case vectorBucketName = "vectorBucketName"
            case vectors = "vectors"
        }
    }

    public struct PutVectorsOutput: AWSDecodableShape {
        public init() {}
    }

    public struct QueryOutputVector: AWSDecodableShape {
        /// The vector data associated with the vector, if requested.
        public let data: VectorData?
        /// The measure of similarity between the vector in the response and the query vector.
        public let distance: Float?
        /// The key of the vector in the approximate nearest neighbor search.
        public let key: String
        /// The metadata associated with the vector, if requested.
        public let metadata: AWSDocument?

        @inlinable
        public init(data: VectorData? = nil, distance: Float? = nil, key: String, metadata: AWSDocument? = nil) {
            self.data = data
            self.distance = distance
            self.key = key
            self.metadata = metadata
        }

        private enum CodingKeys: String, CodingKey {
            case data = "data"
            case distance = "distance"
            case key = "key"
            case metadata = "metadata"
        }
    }

    public struct QueryVectorsInput: AWSEncodableShape {
        /// Metadata filter to apply during the query. For more information about metadata keys, see Metadata filtering in the Amazon S3 User Guide.
        public let filter: AWSDocument?
        /// The ARN of the vector index that you want to query.
        public let indexArn: String?
        /// The name of the vector index that you want to query.
        public let indexName: String?
        /// The query vector. Ensure that the query vector has the same dimension as the dimension of the vector index that's being queried. For example, if your vector index contains vectors with 384 dimensions, your query vector must also have 384 dimensions.
        public let queryVector: VectorData
        /// Indicates whether to include the computed distance in the response. The default value is false.
        public let returnDistance: Bool?
        /// Indicates whether to include metadata in the response. The default value is false.
        public let returnMetadata: Bool?
        /// The number of results to return for each query.
        public let topK: Int
        /// The name of the vector bucket that contains the vector index.
        public let vectorBucketName: String?

        @inlinable
        public init(filter: AWSDocument? = nil, indexArn: String? = nil, indexName: String? = nil, queryVector: VectorData, returnDistance: Bool? = nil, returnMetadata: Bool? = nil, topK: Int, vectorBucketName: String? = nil) {
            self.filter = filter
            self.indexArn = indexArn
            self.indexName = indexName
            self.queryVector = queryVector
            self.returnDistance = returnDistance
            self.returnMetadata = returnMetadata
            self.topK = topK
            self.vectorBucketName = vectorBucketName
        }

        public func validate(name: String) throws {
            try self.validate(self.indexName, name: "indexName", parent: name, max: 63)
            try self.validate(self.indexName, name: "indexName", parent: name, min: 3)
            try self.validate(self.topK, name: "topK", parent: name, min: 1)
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, max: 63)
            try self.validate(self.vectorBucketName, name: "vectorBucketName", parent: name, min: 3)
        }

        private enum CodingKeys: String, CodingKey {
            case filter = "filter"
            case indexArn = "indexArn"
            case indexName = "indexName"
            case queryVector = "queryVector"
            case returnDistance = "returnDistance"
            case returnMetadata = "returnMetadata"
            case topK = "topK"
            case vectorBucketName = "vectorBucketName"
        }
    }

    public struct QueryVectorsOutput: AWSDecodableShape {
        /// The vectors in the approximate nearest neighbor search.
        public let vectors: [QueryOutputVector]

        @inlinable
        public init(vectors: [QueryOutputVector]) {
            self.vectors = vectors
        }

        private enum CodingKeys: String, CodingKey {
            case vectors = "vectors"
        }
    }

    public struct VectorBucket: AWSDecodableShape {
        /// Date and time when the vector bucket was created.
        public let creationTime: Date
        /// The encryption configuration for the vector bucket.
        public let encryptionConfiguration: EncryptionConfiguration?
        /// The Amazon Resource Name (ARN) of the vector bucket.
        public let vectorBucketArn: String
        /// The name of the vector bucket.
        public let vectorBucketName: String

        @inlinable
        public init(creationTime: Date, encryptionConfiguration: EncryptionConfiguration? = nil, vectorBucketArn: String, vectorBucketName: String) {
            self.creationTime = creationTime
            self.encryptionConfiguration = encryptionConfiguration
            self.vectorBucketArn = vectorBucketArn
            self.vectorBucketName = vectorBucketName
        }

        private enum CodingKeys: String, CodingKey {
            case creationTime = "creationTime"
            case encryptionConfiguration = "encryptionConfiguration"
            case vectorBucketArn = "vectorBucketArn"
            case vectorBucketName = "vectorBucketName"
        }
    }

    public struct VectorBucketSummary: AWSDecodableShape {
        /// Date and time when the vector bucket was created.
        public let creationTime: Date
        /// The Amazon Resource Name (ARN) of the vector bucket.
        public let vectorBucketArn: String
        /// The name of the vector bucket.
        public let vectorBucketName: String

        @inlinable
        public init(creationTime: Date, vectorBucketArn: String, vectorBucketName: String) {
            self.creationTime = creationTime
            self.vectorBucketArn = vectorBucketArn
            self.vectorBucketName = vectorBucketName
        }

        private enum CodingKeys: String, CodingKey {
            case creationTime = "creationTime"
            case vectorBucketArn = "vectorBucketArn"
            case vectorBucketName = "vectorBucketName"
        }
    }

    public struct VectorData: AWSEncodableShape & AWSDecodableShape {
        /// The vector data as 32-bit floating point numbers. The number of elements in this array must exactly match the dimension of the vector index where the operation is being performed.
        public let float32: [Float]?

        @inlinable
        public init(float32: [Float]? = nil) {
            self.float32 = float32
        }

        private enum CodingKeys: String, CodingKey {
            case float32 = "float32"
        }
    }
}

// MARK: - Errors

/// Error enum for S3Vectors
public struct S3VectorsErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case conflictException = "ConflictException"
        case internalServerException = "InternalServerException"
        case kmsDisabledException = "KmsDisabledException"
        case kmsInvalidKeyUsageException = "KmsInvalidKeyUsageException"
        case kmsInvalidStateException = "KmsInvalidStateException"
        case kmsNotFoundException = "KmsNotFoundException"
        case notFoundException = "NotFoundException"
        case serviceQuotaExceededException = "ServiceQuotaExceededException"
        case serviceUnavailableException = "ServiceUnavailableException"
        case tooManyRequestsException = "TooManyRequestsException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize S3Vectors
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// Access denied.
    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    /// The request failed because a vector bucket name or a vector index name already exists. Vector bucket names must be unique within your Amazon Web Services account for each Amazon Web Services Region. Vector index names must be unique within your vector bucket. Choose a different vector bucket name or vector index name, and try again.
    public static var conflictException: Self { .init(.conflictException) }
    /// The request failed due to an internal server error.
    public static var internalServerException: Self { .init(.internalServerException) }
    /// The specified Amazon Web Services KMS key isn't enabled.
    public static var kmsDisabledException: Self { .init(.kmsDisabledException) }
    /// The request was rejected for one of the following reasons:    The KeyUsage value of the KMS key is incompatible with the API operation.   The encryption algorithm or signing algorithm specified for the operation is incompatible with the type of key material in the KMS key (KeySpec).   For more information, see InvalidKeyUsageException in the Amazon Web Services Key Management Service API Reference.
    public static var kmsInvalidKeyUsageException: Self { .init(.kmsInvalidKeyUsageException) }
    /// The key state of the KMS key isn't compatible with the operation. For more information, see KMSInvalidStateException in the Amazon Web Services Key Management Service API Reference.
    public static var kmsInvalidStateException: Self { .init(.kmsInvalidStateException) }
    /// The KMS key can't be found.
    public static var kmsNotFoundException: Self { .init(.kmsNotFoundException) }
    /// The request was rejected because the specified resource can't be found.
    public static var notFoundException: Self { .init(.notFoundException) }
    /// Your request exceeds a service quota.
    public static var serviceQuotaExceededException: Self { .init(.serviceQuotaExceededException) }
    /// The service is unavailable. Wait briefly and retry your request. If it continues to fail, increase your waiting time between retries.
    public static var serviceUnavailableException: Self { .init(.serviceUnavailableException) }
    /// The request was denied due to request throttling.
    public static var tooManyRequestsException: Self { .init(.tooManyRequestsException) }
    /// The requested action isn't valid.
    public static var validationException: Self { .init(.validationException) }
}

extension S3VectorsErrorType: Equatable {
    public static func == (lhs: S3VectorsErrorType, rhs: S3VectorsErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension S3VectorsErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
